#include <iostream>
#include <queue>
using namespace std;

struct G_edge {
	int a;
	int b;
	int cost;
	G_edge(int a, int b) :a(a), b(b) { };
};

bool operator < (G_edge lhs, G_edge rhs) {
	return (lhs.cost > rhs.cost);
}

int N, Q;
priority_queue<G_edge> EDGE;
int FL[105];

void input() {
	for (int i=1; i<=N; i++) {
		for (int j=1; j<=N; j++) {
			G_edge e = G_edge(i, j);
			cin >> e.cost;
			if (i==j) continue;
			EDGE.push(e);
		}
	}
	for (int i=1; i<=N; i++) {
		FL[i] = i;
	}
	cin >> Q;
	for (int i=1; i<=Q; i++) {
		int a, b;
		cin >> a >> b;
		int fla = FL[a];
		int flb = FL[b];
		if (fla != flb) {
			for (int j=1; j<=N; j++) {
				if (FL[j] == flb) {
					FL[j] = fla;
				}
			}
		}
	}
}

int Kruskal() {
	int route = 0;
	while (!EDGE.empty()) {
		G_edge e = EDGE.top(); EDGE.pop();
		int a = e.a;
		int b = e.b;
		int fla = FL[a];
		int flb = FL[b];
		if (FL[a] != FL[b]) {
			
			for (int j=1; j<=N; j++) {
				if (FL[j] == flb) {
					FL[j] = fla;
				}
			}
			route += e.cost;
		}
	}
	return route;
}

int main() {
	while ((cin >> N)) {
		input();
		int min = Kruskal();
		cout << min << endl;
	}
}
